package com.example.boot3.rpc.util;


import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Stack;
import java.util.stream.Collectors;

public class CalculatorService {

    public static double calculate(String expression) {
        int i = expression.indexOf(",");
        if(i!=-1){
            String substring = expression.substring(expression.indexOf("(")+1, expression.indexOf(")"));
            String[] split = substring.split(",");
            List<String> strings = Arrays.asList(split);
            List<Double> list = strings.stream().map(Double::valueOf).collect(Collectors.toList());
            String sub2 = expression.substring(0, expression.indexOf("("));
            return evaluateMultiArgFunction(sub2,list);
        }
        // 预处理表达式
        expression = preprocessExpression(expression);

        // 使用双栈法计算表达式
        double v = evaluateExpression(expression);
        return v;
    }

    private static String preprocessExpression(String expression) {
        // 移除空格，转换为小写（为了函数识别）
        expression = expression.replaceAll("\\s+", "").toLowerCase();

        // 处理函数名称
        expression = expression.replaceAll("sin", "s")
                .replaceAll("cos", "c")
                .replaceAll("tan", "t")
                .replaceAll("sqrt", "q")
                .replaceAll("log", "l")
                .replaceAll("max", "m")
                .replaceAll("min", "n")
                .replaceAll("avg", "a")
                .replaceAll("abs","a");

        return expression;
    }

    private static double evaluateExpression(String expression) {
        Stack<Double> numbers = new Stack<>();
        Stack<Character> operators = new Stack<>();

        for (int i = 0; i < expression.length(); i++) {
            char c = expression.charAt(i);

            if (Character.isDigit(c) || c == '.') {
                // 处理数字
                StringBuilder sb = new StringBuilder();
                while (i < expression.length() &&
                        (Character.isDigit(expression.charAt(i)) || expression.charAt(i) == '.')) {
                    sb.append(expression.charAt(i++));
                }
                i--;
                numbers.push(Double.parseDouble(sb.toString()));
            } else if (c == '(') {
                operators.push(c);
            } else if (c == ')') {
                while (operators.peek() != '(') {
                    numbers.push(applyOperation(operators.pop(), numbers.pop(), numbers.pop()));
                }
                operators.pop();

                // 检查括号后是否是函数
                if (!operators.isEmpty() && isFunction(operators.peek())) {
                    numbers.push(applyFunction(operators.pop(), numbers.pop()));
                }
            } else if (isOperator(c) || isFunction(c)) {
                while (!operators.isEmpty() && hasPrecedence(c, operators.peek())) {
                    if (isFunction(operators.peek())) {
                        numbers.push(applyFunction(operators.pop(), numbers.pop()));
                    } else {
                        numbers.push(applyOperation(operators.pop(), numbers.pop(), numbers.pop()));
                    }
                }
                operators.push(c);
            }
        }

        while (!operators.isEmpty()) {
            if (isFunction(operators.peek())) {
                numbers.push(applyFunction(operators.pop(), numbers.pop()));
            } else {
                numbers.push(applyOperation(operators.pop(), numbers.pop(), numbers.pop()));
            }
        }

        return numbers.pop();
    }

    private static boolean isOperator(char c) {
        return c == '+' || c == '-' || c == '*' || c == '/' || c == '^';
    }

    private static boolean isFunction(char c) {
        return c == 's' || c == 'c' || c == 't' || c == 'q' || c == 'l' || c == 'm' || c == 'n' || c == 'a';
    }

    private static boolean hasPrecedence(char op1, char op2) {
        if (op2 == '(' || op2 == ')') return false;
        if ((op1 == '^') && (op2 == '*' || op2 == '/' || op2 == '+' || op2 == '-')) return false;
        if ((op1 == '*' || op1 == '/') && (op2 == '+' || op2 == '-')) return false;
        return true;
    }

    private static double applyOperation(char op, double b, double a) {
        switch (op) {
            case '+': return a + b;
            case '-': return a - b;
            case '*': return a * b;
            case '/':
                if (b == 0) throw new ArithmeticException("Division by zero");
                return a / b;
            case '^': return Math.pow(a, b);
        }
        return 0;
    }

    private static double applyFunction(char func, double a) {
        switch (func) {
            case 's': return Math.sin(Math.toRadians(a)); // 假设输入是度数
            case 'c': return Math.cos(Math.toRadians(a));
            case 't': return Math.tan(Math.toRadians(a));
            case 'q': return Math.sqrt(a);
            case 'l': return Math.log10(a); // 常用对数
            case 'a': return Math.abs(a);
        }
        return a;
    }

    // 处理多参数函数（max, min, avg）
    public static double evaluateMultiArgFunction(String function, List<Double> args) {
        switch (function) {
            case "max":
                return Collections.max(args);
            case "min":
                return Collections.min(args);
            case "avg":
                return args.stream().mapToDouble(Double::doubleValue).average().orElse(0);
            default:
                throw new IllegalArgumentException("Unknown function: " + function);
        }
    }
}